package com.bupt.ilink.service.innovationPlaza;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bupt.ilink.entity.innovationPlaza.AnnouncementInfo;
import com.bupt.ilink.entity.innovationPlaza.CompetitionMetadata;
import com.bupt.ilink.entity.innovationPlaza.DTO.CompetitionResponse;
import com.bupt.ilink.entity.innovationPlaza.DTO.ProjectResponse;
import com.bupt.ilink.entity.innovationPlaza.InnovationTags;
import com.bupt.ilink.mapper.innovationPlaza.*;
import com.bupt.ilink.service.MinioService;
//import jakarta.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CompetitionService {

    @Autowired
    private CompetitionMapper competitionMapper;
    @Autowired
    private UserLikeMapper userLikeMapper;

    @Autowired
    private InnovationTagsMapper innovationTagsMapper;

    @Autowired
    private InnovationConnectTagsMapper innovationConnectTagsMapper;

    @Autowired
    private AnnouncementInfoMapper announcementInfoMapper;

    @Autowired
    private MinioService minioService;

    public List<InnovationTags> getCommonTags() { return innovationTagsMapper.selectCommonCompetitionTags(); }

    public IPage<CompetitionResponse> getAllCompetitions(String sentence, List<String> tags,String sortBy, int pageNum, int pageSize,String userId) {
        Page<CompetitionResponse> page = new Page<>(pageNum, pageSize);

        IPage<CompetitionResponse> competitionResponsePage=competitionMapper.getAllCompetitions(page, sortBy);

        List<CompetitionResponse> competitionResponses=competitionResponsePage.getRecords();

        // 获取每个赛事的标签并设置
        for (CompetitionResponse competitionResponse : competitionResponses) {
            List<String> projectTags = innovationTagsMapper.getTagsByProjectId(competitionResponse.getCompetitionId());
            competitionResponse.setTags(projectTags);
            //获取收藏状态
            int count = userLikeMapper.countUserCollect(competitionResponse.getCompetitionId(), userId);
            competitionResponse.setLikeTrue(count > 0);

        }

        if (tags.contains("全部")) {
            // 将 tags 修改为空列表
            tags.clear();
        }
        // 按需过滤项目
        List<CompetitionResponse> filteredCompetitions = competitionResponses;
        boolean filterByTags = tags != null && !tags.isEmpty();
        boolean filterBySentence = sentence != null && !sentence.isEmpty();

        if (filterByTags && filterBySentence) {
            // 同时过滤标签和模糊查询
            filteredCompetitions = competitionResponses.stream()
                    .filter(competition -> competition.getTags() != null && !competition.getTags().isEmpty() && new HashSet<>(competition.getTags()).containsAll(tags))
                    .filter(competition -> competition.getName() != null && competition.getName().contains(sentence))
                    .collect(Collectors.toList());
        }else if (filterByTags) {
            // 根据标签进行过滤
            filteredCompetitions = filteredCompetitions.stream()
                    .filter(competition -> competition.getTags() != null && !competition.getTags().isEmpty() && new HashSet<>(competition.getTags()).containsAll(tags))
                    .collect(Collectors.toList());
        }else if (filterBySentence) {
            // 进行模糊查询过滤
            filteredCompetitions = filteredCompetitions.stream()
                    .filter(competition -> competition.getName() != null && competition.getName().contains(sentence))
                    .collect(Collectors.toList());
        }


        // 设置过滤后的数据到分页对象中
        page.setRecords(filteredCompetitions);
        page.setTotal(competitionResponsePage.getTotal());
        page.setPages(competitionResponsePage.getPages());
//        page.setSize(competitionResponsePage.getSize());
        page.setCurrent(competitionResponsePage.getCurrent());
        page.setTotal(filteredCompetitions.size());

        return page;

    }

    public IPage<CompetitionResponse> getAllCompetitionsEnd(String sentence, List<String> tags, String sortBy, int pageNum, int pageSize, String userId) {
        // Step 1: 从数据库中获取按排序的所有数据
        List<CompetitionResponse> competitionResponses = competitionMapper.getAllCompetitionsNopage(sortBy);

        // Step 2: 获取每个赛事的标签并设置
        for (CompetitionResponse competitionResponse : competitionResponses) {
            List<String> projectTags = innovationTagsMapper.getTagsByProjectId(competitionResponse.getCompetitionId());
            competitionResponse.setTags(projectTags);

            // 获取收藏状态
            int count = userLikeMapper.countUserCollect(competitionResponse.getCompetitionId(), userId);
            competitionResponse.setLikeTrue(count > 0);
        }

        // Step 3: 处理标签过滤条件
        if (tags.contains("全部")) {
            tags.clear();  // 将 tags 修改为空列表
        }
        // 按需过滤项目
        List<CompetitionResponse> filteredCompetitions = competitionResponses;
        boolean filterByTags = tags != null && !tags.isEmpty();
        boolean filterBySentence = sentence != null && !sentence.isEmpty();

        if (filterByTags && filterBySentence) {
            // 同时过滤标签和模糊查询
            filteredCompetitions = competitionResponses.stream()
                    .filter(competition -> competition.getTags() != null && !competition.getTags().isEmpty() && new HashSet<>(competition.getTags()).containsAll(tags))
                    .filter(competition -> competition.getName() != null && competition.getName().contains(sentence))
                    .collect(Collectors.toList());
        }else if (filterByTags) {
            // 根据标签进行过滤
            filteredCompetitions = filteredCompetitions.stream()
                    .filter(competition -> competition.getTags() != null && !competition.getTags().isEmpty() && new HashSet<>(competition.getTags()).containsAll(tags))
                    .collect(Collectors.toList());
        }else if (filterBySentence) {
            // 进行模糊查询过滤
            filteredCompetitions = filteredCompetitions.stream()
                    .filter(competition -> competition.getName() != null && competition.getName().contains(sentence))
                    .collect(Collectors.toList());
        }

//        // Step 4: 根据 tags 和 sentence 进行过滤
//        List<CompetitionResponse> filteredCompetitions = competitionResponses.stream()
//                .filter(competition -> {
//                    boolean matchesTags = tags == null || tags.isEmpty() || (competition.getTags() != null && !competition.getTags().isEmpty() && new HashSet<>(competition.getTags()).containsAll(tags));
//                    boolean matchesSentence = sentence == null || sentence.isEmpty() || (competition.getName() != null && competition.getName().contains(sentence));
//                    return matchesTags && matchesSentence;
//                })
//                .collect(Collectors.toList());

        // Step 5: 手动分页
        int total = filteredCompetitions.size();
        int start = (pageNum - 1) * pageSize;
        int end = Math.min(start + pageSize, total);
        List<CompetitionResponse> pagedCompetitions = filteredCompetitions.subList(start, end);

        // Step 6: 设置分页对象
        Page<CompetitionResponse> page = new Page<>(pageNum, pageSize);
        page.setRecords(pagedCompetitions);
        page.setTotal(total);
        page.setPages((int) Math.ceil((double) total / pageSize));

        return page;

    }


    //获取赛事详细信息
    public CompetitionResponse getAnnouncementInfoById(Long competitionId, String userId) {


        List<AnnouncementInfo> announcementInfos = announcementInfoMapper.selectByForeignKeyId(competitionId);
        CompetitionMetadata competitionMetadata =competitionMapper.selectById(competitionId);

        if (announcementInfos == null) {
            throw new RuntimeException("Announcement not found with id " + competitionId);
        }
        //考虑要不要直接改为CompetitionResponse
        CompetitionResponse dto = new CompetitionResponse();
        dto.setCompetitionId(competitionMetadata.getCompetitionId());
        dto.setText(competitionMetadata.getText());
        dto.setName(competitionMetadata.getName());
        dto.setDescription(competitionMetadata.getDescription());
        dto.setLikeNum(competitionMetadata.getLikeNum());
//        dto.getLookNum(competitionMetadata.getLookNum());
        dto.setLookNum(competitionMetadata.getLookNum());
        dto.setPublisherTime(competitionMetadata.getPublisherTime());
        dto.setShareNum(competitionMetadata.getShareNum());
        dto.setStatus(competitionMetadata.getStatus());

        List<String> projectTags = innovationTagsMapper.getTagsByProjectId(dto.getCompetitionId());
        dto.setTags(projectTags);
        //获取收藏状态
        int count = userLikeMapper.countUserCollect(competitionId, userId);
        if  (count > 0){
            dto.setLikeTrue(true);
        }

        Map<String, String> URLs=new HashMap<>();
        for(AnnouncementInfo announcementInfo : announcementInfos){
            boolean filterByFilePath = announcementInfo.getFilePath() != null && !announcementInfo.getFilePath().isEmpty();
            boolean filterByFileName = announcementInfo.getFileName() != null && !announcementInfo.getFileName().isEmpty();
            boolean filterByminio = filterByFilePath && filterByFileName;
            if (filterByminio){

                URLs.put(announcementInfo.getFileName(),(minioService.getImageUrlWithAnyFormat(announcementInfo.getFilePath() + announcementInfo.getFileName())));
            }
        }
        dto.setFiles(URLs);
        return dto;
    }
    //已经修改为对收藏的判断
    @Transactional // 保证方法的事务执行，避免多步操作时出现数据不一致
    public String toggleLike(Long competitionId, String userId) {
//        int count = userLikeMapper.countUserLike(competitionId, userId);
        int count = userLikeMapper.countUserCollect(competitionId, userId);
        if (count > 0) {
//            userLikeMapper.deleteUserLike(competitionId, userId);
            userLikeMapper.deleteUserCollect(competitionId,userId);
            competitionMapper.decrementLikeNum(competitionId);
            return "取消收藏";
        } else {
//            userLikeMapper.insertUserLike(competitionId, userId);
            userLikeMapper.insertUserCollect(competitionId,userId);//"Competition"
            competitionMapper.incrementLikeNum(competitionId);
            return "成功收藏";
        }
    }

    // 赛事浏览状态更新
    public boolean incrementLookNum(Long competitionId) {
        return competitionMapper.incrementLookNum(competitionId) > 0;
    }

    // 赛事分享更新
    public boolean incrementShareNum(Long competitionId) {
        return competitionMapper.incrementShareNum(competitionId) > 0;
    }
    //文档下载
    public File downloadFileFromUrl(String fileUrl) throws IOException {
        URL url = new URL(fileUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");

        // 设置文件名为URL中的文件名部分
        String fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);

        // 创建临时文件
        File tempFile = File.createTempFile(fileName, ".tmp");
        tempFile.deleteOnExit(); // JVM退出时删除临时文件

        try (InputStream inputStream = connection.getInputStream();
             FileOutputStream outputStream = new FileOutputStream(tempFile)) {

            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        }

        return tempFile;
    }
    private static final int MAX_RETRIES = 3; // 最大重试次数
    private static final int RETRY_DELAY_MS = 20000; // 每次重试间隔20秒
    //后端代理访问OSS链接
    public ResponseEntity<Object> getFileFromLink(String link) {
        int attempts = 0;
        while (attempts < MAX_RETRIES) {
            attempts=attempts+1;
            try {
                // 设置超时时间
                int connectTimeout = 120000; // 120秒
                int readTimeout = 120000;    // 120秒

                URL url = new URL(link);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");

                // 设置连接超时和读取超时
                connection.setConnectTimeout(connectTimeout);
                connection.setReadTimeout(readTimeout);

                // 检查响应代码
                int responseCode = connection.getResponseCode();
                if (responseCode != HttpURLConnection.HTTP_OK) {
                    return ResponseEntity.status(responseCode).body("无法访问指定链接");
                }

                InputStream inputStream = connection.getInputStream();
                InputStreamResource resource = new InputStreamResource(inputStream);

                // 返回文件内容给前端
                return ResponseEntity.ok()
                        .contentType(MediaType.APPLICATION_OCTET_STREAM)
                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=announcement.docx")
                        .body(resource);

            } catch (Exception e) {
                if (attempts >= MAX_RETRIES) {
                    return ResponseEntity.status(500).body("服务器内部错误：" + e.getMessage());
                }
                // 重试前等待一段时间
                try {
                    Thread.sleep(RETRY_DELAY_MS);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    return ResponseEntity.status(500).body("服务器内部错误：" + ie.getMessage());
                }
            }
        }
        return ResponseEntity.status(500).body("服务器无法处理请求");
    }

}
